package com.sgcc.pda.hw.binder;

import android.Manifest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.cepri.service.IDEVBaseInterface;
import com.cepri.service.yingxiao.DtsManager;
import com.cepri.service.yingxiao.MediaPlayerManager;
import com.cepri.service.yingxiao.ZxingManager;
import com.cepri.service.yingxiao.baidutts.BaiduTtsManager;
import com.cepri.service.yingxiao.baidutts.ITtsManager;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.sgcc.pda.baselibrary.utils.ToastUtils;
import com.sgcc.pda.common.aidl.CommonCallback;
import com.sgcc.pda.common.aidl.CommonParams;
import com.sgcc.pda.common.aidl.CommonResults;
import com.sgcc.pda.mdrh.task.safelibrary.BuildConfig;
import com.sgcc.pda.mdrh.utils.FileUtils;
import com.sgcc.pda.sdk.utils.NetWorkUtil;
import com.sgcc.pda.sdk.utils.SharePrefUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;


/**
 * 掌机基础服务接口-封装给插件APP通过Binder调用
 *
 * @author Ben
 * @date 2019/06/06
 */
public class IDEVBaseBinderUtil {
    /**
     * 成功字段
     */
    private static final String SUCCESS = "success";
    /**
     * 是否设置成功
     */
    private static final String IS_SUCCESS = "isSuccess";

    private static final String TAG = "IDEVBaseBinderUtil";
    static final String CLASS_NAME = "com.cepri.service.binder.IDEVBaseBinderUtil";

    private IDEVBaseInterface mIDEVBaseService = null;
    private boolean isBind = false;
    //语音播放管理类
    private ITtsManager mTtsManager;

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mIDEVBaseService = IDEVBaseInterface.Stub.asInterface(service);
            isBind = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBind = false;
            mIDEVBaseService = null;
        }
    };

    private IDEVBaseBinderUtil() {
        //初始化语音合成
        if (BuildConfig.USE_BAIDU_TTS) {
            mTtsManager = BaiduTtsManager.getInstance();
        } else {
            mTtsManager = DtsManager.getInstance();
        }
    }

    private static class Instance {
        private static final IDEVBaseBinderUtil mInstance = new IDEVBaseBinderUtil();
    }

    /**
     * 单例
     */
    public static IDEVBaseBinderUtil getInstance() {
        return Instance.mInstance;
    }

    /**
     * 绑定掌机基础服务提供接口的AIDL服务
     *
     * @param context
     * @return 是否绑定
     */
    public boolean bind(Context context) {
        if (isBind) {
            return isBind;
        }
        Intent intent = new Intent(IDEVBaseInterface.class.getName());
        intent.setClassName("com.cepri.service", "com.cepri.service.IDEVBaseServer");
        try {
            isBind = context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        } catch (Exception e) {
            Log.e(TAG, "bind: " + e.getMessage());
            isBind = false;
        }
        return isBind;
    }

    /**
     * 取消绑定掌机基础服务提供接口的AIDL服务
     *
     * @param context
     * @return 是否绑定
     */
    public void unbind(Context context) {
        try {
            context.unbindService(mConnection);
        } catch (Exception e) {
            Log.e(TAG, "unbind: " + e.getMessage());
        }
    }

    /**
     * 根据方法名执行对应的方法
     *
     * @param params   参数
     * @param callback 回调
     * @return 结果
     */
    public CommonResults execute(CommonParams params, CommonCallback callback) {
        String methodName = params.getMethodName();
        try {
            // 通过反射调用方法，方法参数与返回值必须统一成（CommonParams，CommonCallback，CommonResults）
            Method method = getClass().getMethod(methodName, CommonParams.class, CommonCallback.class);
            return (CommonResults) method.invoke(this, params, callback);
        } catch (Exception e) {
            Log.e(TAG, "execute: " + e.getMessage());
            return new CommonResults("-2", e.getMessage());
        }
    }

    /**
     * 调用相机拍照或者获取相册图片
     */
    public void takePhoto(CommonParams params, CommonCallback callback) {
        Activity a = (Activity) params.getParam("activity");
        int imgNum = params.getInt("imgNum", 1);
        //工作票编号
        String wtNo = params.getString("wtNo");
        SharePrefUtil.saveString(a, "wtNo", wtNo + "");
        boolean openCamera = params.getBoolean("isCamera", false);
        //是否支持视频
        boolean supportVideo = params.getBoolean("supportVideo", false);
        int mimeType = PictureMimeType.ofImage();
        if (openCamera) {
            if (supportVideo) {
                mimeType = PictureMimeType.ofVideo();
            }
            PictureSelector.create(a)
                    .openCamera(mimeType)
                    .maxSelectNum(imgNum)
                    .isCamera(true)
                    .imageSpanCount(4)
                    .previewImage(true)
                    .imageFormat(PictureMimeType.PNG)
                    .sizeMultiplier(0.5f)
                    .compress(true)
                    .minimumCompressSize(100)
                    .recordVideoSecond(60)
                    .videoQuality(0)
                    .forResult(PictureConfig.CHOOSE_REQUEST);
        } else {
            if (supportVideo) {
                mimeType = PictureMimeType.ofAll();
            }
            PictureSelector.create(a)
                    .openGallery(mimeType)
                    .maxSelectNum(imgNum)
                    .isCamera(false)
                    .imageSpanCount(4)
                    .previewImage(false)
                    .imageFormat(PictureMimeType.PNG)
                    .sizeMultiplier(0.5f)
                    .compress(true)
                    .minimumCompressSize(100)
                    .videoMaxSecond(60)
                    .forResult(PictureConfig.CHOOSE_REQUEST);
        }
    }


    /**
     * 设置系统时钟
     * <p>
     * dateTime 设置日期时间值的字符串yyyy-MM-dd HH:mm:ss，如2016-10-28 16:34:45
     *
     * @return 成功返回 true，失败返回 false
     */
    public CommonResults setDateTime(CommonParams params, CommonCallback callback) throws RemoteException {
        String dateTime = params.getString("dateTime");
        boolean value = mIDEVBaseService.setDateTime(dateTime);
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, value);
        return results;
    }

    /**
     * 添加 APN 设置，同时设置为默认
     * <p>
     * apnName  APN 设置的名称标识
     * apn      APN 内容
     * userName 用户名，可为空或 null
     * password 密码，可为空或 null
     *
     * @return 成功返回 true，失败返回 false
     */
    public CommonResults addApn(CommonParams params, CommonCallback callback) throws RemoteException {
        String apnName = params.getString("apnName");
        String apn = params.getString("apn");
        String userName = params.getString("userName");
        String password = params.getString("password");

        boolean value = mIDEVBaseService.addApn(apnName, apn, userName, password);
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, value);
        return results;
    }

    /**
     * 删除 APN 设置
     * <p>
     * apn 要删除的 APN 设置项对应的 APN 内容
     *
     * @return 成功返回 true，失败返回 false
     */
    public CommonResults deleteApn(CommonParams params, CommonCallback callback) throws RemoteException {
        String apn = params.getString("apn");

        boolean value = mIDEVBaseService.deleteApn(apn);
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, value);
        return results;
    }

    /**
     * 获取设备型号
     *
     * @return 成功返回设备型号，失败返回空字符串
     */
    public CommonResults getDeviceModel(CommonParams params, CommonCallback callback) throws RemoteException {

        String value = mIDEVBaseService.getDeviceModel();
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("equipmentType", value);
        return results;
    }

    /**
     * 获取设备序列号
     *
     * @return 成功返回设备序列号，失败返回空字符串
     */
    public CommonResults getDeviceSn(CommonParams params, CommonCallback callback) throws RemoteException {

        String value = mIDEVBaseService.getDeviceSn();
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("equipmentSerialNum", value);
        return results;
    }

    /**
     * 获取设备系统版本号
     *
     * @return 成功返回设备系统版本号，失败返回空字符串
     */
    public CommonResults getOSVersion(CommonParams params, CommonCallback callback) throws RemoteException {

        String value = mIDEVBaseService.getOSVersion();
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("equipmentSystemVersionNum", value);
        return results;
    }

    /**
     * 获取设备硬件版本号
     *
     * @return 成功返回设备硬件版本号，失败返回空字符串
     */
    public CommonResults getDeviceHardVersion(CommonParams params, CommonCallback callback) throws RemoteException {

        String value = mIDEVBaseService.getDeviceHardVersion();
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("equipmentHwVersionNum", value);
        return results;
    }

    /**
     * 获取设备生产日期
     *
     * @return 成功返回设备生产日期，失败返回空字符串
     */
    public CommonResults getProductionDate(CommonParams params, CommonCallback callback) throws RemoteException {

        String value = mIDEVBaseService.getProductionDate();
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("equipmentProductionDate", value);
        return results;
    }

    /**
     * 设置USB的传输方式
     * <p>
     * mode USB 通讯模式<br>
     * 0x00: 关闭所有通讯<br>
     * 0x01: ADB 通讯<br>
     * 0x02: MTP 通讯<br>
     * 0x04: 大容量存储<br>
     * 可以多种模式同时使用
     *
     * @return 成功返回 true，失败返回 false
     */
    public CommonResults setUSBMode(CommonParams params, CommonCallback callback) throws RemoteException {
        int mode = params.getInt("mode", 0x04);

        boolean value = mIDEVBaseService.setUSBMode(mode);
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, value);
        return results;
    }

    /**
     * 系统升级（会重启设备）
     * <p>
     * filePath 升级文件的绝对路径
     *
     * @return 成功返回 true，失败返回 false
     */
    public CommonResults OSUpdate(CommonParams params, CommonCallback callback) throws RemoteException {
        String filePath = params.getString("filePath");

        boolean value = mIDEVBaseService.OSUpdate(filePath);
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, value);
        return results;
    }

    /**
     * 获取系统校验百分比
     *
     * @return 系统校验百分比
     */
    public CommonResults getOSVerifyPercent(CommonParams params, CommonCallback callback) throws RemoteException {
        int value = mIDEVBaseService.getOSVerifyPercent();
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("systemCheckPercentage", value);
        return results;
    }

    /**
     * 获取系统基础服务的版本
     *
     * @return 成功返回系统基础服务的版本，失败返回空字符串
     */
    public CommonResults getServiceVersion(CommonParams params, CommonCallback callback) throws RemoteException {

        String value = mIDEVBaseService.getServiceVersion();
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("basicServiceVersion", value);
        return results;
    }

    /**
     * 设置 HOME 键的可用状态
     * <p>
     * status HOME 键是否可用的状态
     * true: 可用
     * false: 不可用
     *
     * @return 设置成功返回 true，失败返回 false
     */
    public CommonResults setHomeKeyStatus(CommonParams params, CommonCallback callback) throws RemoteException {
        boolean status = params.getBoolean("status");

        boolean value = mIDEVBaseService.setHomeKeyStatus(status);
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, value);
        return results;
    }

    /**
     * 设置下拉状态栏是否可下拉
     * <p>
     * status 下拉状态栏是否可下拉的状态
     * true: 可下拉
     * false: 不可下拉
     *
     * @return 设置成功返回 true，失败返回 false
     */
    public CommonResults setStatusBarPullable(CommonParams params, CommonCallback callback) throws RemoteException {
        boolean status = params.getBoolean("status");

        boolean value = mIDEVBaseService.setStatusBarPullable(status);
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, value);
        return results;
    }

    /**
     * 语音合成
     *
     * @return 成功返回 true，返回 false
     */
    public CommonResults voice(CommonParams params, CommonCallback callback) throws RemoteException {
        Context context = (Context) params.getParam("activity");
        String strData = params.getString("data");
        String state = params.getString("state");
//        DtsManager.getInstance().init(context);
        if ("0".equals(state)) {
            mTtsManager.play(strData);
        } else if ("1".equals(state)) {
            int playState = mTtsManager.getPlayState();
            if (0 == playState) {
                mTtsManager.play(strData);
            } else {
                mTtsManager.resumeSpeaking();
            }
        } else {
            mTtsManager.pauseSpeaking();
        }
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult(IS_SUCCESS, "");
        return results;
    }

    /**
     * 本地扫描
     *
     * @return 成功返回 true，返回 false
     */
    public void localScan(CommonParams params, final CommonCallback callback) throws RemoteException {
        Context context = (Context) params.getParam("activity");
        ZxingManager manager = ZxingManager.getInstance();
        manager.init(context);
        final CommonResults results = new CommonResults("1", SUCCESS);

        manager.toIntent(context, new ZxingManager.OnScanClickListener() {
            @Override
            public void onResult(String bm) {
                results.addResult("BM", bm);
                callback.callback(results);
            }
        });
    }


    /**
     * 录音
     *
     * @return 成功返回 true，返回 false
     */
    public void record(CommonParams params, final CommonCallback callback) throws RemoteException {
        Activity activity = (Activity) params.getParam("activity");
        String recordState = params.getString("recordState");//0录音，2 停止录音，3 取消录音
        String playState = params.getString("playState");

        MediaPlayerManager manager = MediaPlayerManager.getInstance();
        final CommonResults results = new CommonResults("1", SUCCESS);
        if (!TextUtils.isEmpty(recordState)) {
            //申请权限
            if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) != PackageManager
                    .PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 200);
                ToastUtils.show(activity, "请先开启录音权限");
            } else if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager
                    .PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 200);
                ToastUtils.show(activity, "请先开启存储卡读写权限");
            } else {
                if ("0".equals(recordState)) {
                    manager.record();
                    results.addResult("recordState", "record");
                } else if ("1".equals(recordState)) {
                    manager.stopRecord();
                    results.addResult("recordState", "stopRecord");
                    results.addResult("filePath", manager.getFilePath());
                } else if ("2".equals(recordState)) {
                    manager.cancleRecord();
                    results.addResult("recordState", "cancleRecord");
                }
            }
        } else {
            String filePath = params.getString("filePath");
            if ("0".equals(playState)) {
                if (!TextUtils.isEmpty(filePath)) {
                    manager.play(filePath);
                } else {
                    if (manager.getFilePath().length() > 0) {
                        manager.play();
                    }
                }
                results.addResult("playState", "play");
            } else {
                manager.stopPlay();
                results.addResult("playState", "stopPlay");
            }
        }
        callback.callback(results);

    }

    /**
     * base64转本地文件
     */
    public void saveBase64File(CommonParams params, final CommonCallback callback) {
        final CommonResults results = new CommonResults("1", SUCCESS);
        try {
            Context context = (Context) params.getParam("activity");
            String base64 = params.getString("base64");
            if (base64.startsWith("data:image/png;base64,")) {
                base64 = base64.substring(22);
            }
            String savePath = params.getString("path");
            String fileName = params.getString("fileName");
            String PATH_LOGCAT = "";
            if (Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中
                PATH_LOGCAT = Environment.getExternalStorageDirectory()
                        .getAbsolutePath() + File.separator + savePath;
            } else {// 如果SD卡不存在，就保存到本应用的目录下
                PATH_LOGCAT = context.getFilesDir().getAbsolutePath()
                        + File.separator + savePath;
            }
            File file = new File(PATH_LOGCAT);
            if (!file.exists()) {
                file.mkdirs();

            }
            byte[] buffer = Base64.decode(base64, Base64.DEFAULT);
            FileOutputStream out = null;

            out = new FileOutputStream(PATH_LOGCAT + File.separator + fileName);
            out.write(buffer);
            out.close();

            results.addResult("PATH_LOGCAT", PATH_LOGCAT + File.separator + fileName);
            callback.callback(results);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 本地文件转base64
     */
    public void file2Base64(CommonParams params, final CommonCallback callback) {
        final CommonResults results = new CommonResults("1", SUCCESS);
        try {
            Context context = (Context) params.getParam("activity");
            String path = params.getString("path");//图片本地地址
            String imgBase64 = FileUtils.compressImageFile(context, path);
            results.addResult("RESULT", imgBase64);
            callback.callback(results);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭Activity
     */
    public void finishActivity(CommonParams params, final CommonCallback callback) {
        Activity activity = (Activity) params.getParam("activity");
        if (activity != null) {
            activity.finish();
        }
    }

    /**
     * 打开相机
     */
    public void openCamera(CommonParams params, final CommonCallback callback) {
        Activity activity = (Activity) params.getParam("activity");
        activity.startActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA));
    }

    /**
     * 获取音频长度
     */
    public void getAudioDuration(CommonParams params, CommonCallback callback) {
        Activity act = (Activity) params.getParam("activity");
        String audioUrl = params.getString("audioUrl");
        int duration = 0;
        try {
            MediaPlayer mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource(audioUrl);
            mediaPlayer.prepare();
            duration = mediaPlayer.getDuration();
            //释放资源
            mediaPlayer.release();

        } catch (Exception e) {
            e.printStackTrace();
        }
        CommonResults results = new CommonResults("1", SUCCESS);
        results.addResult("duration", duration);
        if (callback != null) {
            callback.callback(results);
        }
    }

    /**
     * 判断网络是否连接
     */
    public void isConnect(CommonParams params, final CommonCallback callback) {
        Activity activity = (Activity) params.getParam("activity");
        final CommonResults results = new CommonResults("1", SUCCESS);
        boolean state = NetWorkUtil.getInstance().isConnected(activity);
        results.addResult("connect", state + "");
        callback.callback(results);
    }

}
